package com.sx.pipeline.ui.map

import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Bundle
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.widget.LinearLayout
import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.android.arouter.facade.annotation.Route
import com.amap.api.location.AMapLocation
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.CoordinateConverter
import com.amap.api.maps.LocationSource
import com.amap.api.maps.model.*
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.core.PoiItem
import com.amap.api.services.core.SuggestionCity
import com.amap.api.services.geocoder.*
import com.amap.api.services.poisearch.PoiResult
import com.amap.api.services.poisearch.PoiSearch
import com.blankj.utilcode.util.KeyboardUtils
import com.blankj.utilcode.util.ToastUtils
import com.hjq.bar.TitleBar
import com.sx.mvvmlibs.bus.RxBus
import com.sx.mvvmlibs.utils.Logs
import com.sx.pipeline.R
import com.sx.pipeline.app.base.CYBaseAppBarActivity
import com.sx.pipeline.app.event.BusEvent
import com.sx.pipeline.app.event.EventTypes
import com.sx.pipeline.app.model.CYBaseViewModel
import com.sx.pipeline.arouth.RoutePath
import com.sx.pipeline.databinding.ActSearchLocationBinding


/**
 * @Author: YY
 * @Date: 2022/5/6
 * @Description: 搜索位置
 */
//@Route(path = RoutePath.Main.SEARCH_LOCATION)
class SearchLocationActivity: CYBaseAppBarActivity<ActSearchLocationBinding, CYBaseViewModel>(
    R.layout.act_search_location), LocationSource, AMapLocationListener, PoiSearch.OnPoiSearchListener {

    private lateinit var aMap: AMap

    // 定位
    private var mListener: LocationSource.OnLocationChangedListener? = null
    private var mLocationClient: AMapLocationClient? = null
    private var mLocationOption: AMapLocationClientOption? = null

    private var point: LatLng? = null
    private var marker: Marker? = null
    private var getZoomB: Float? = 16f

    private lateinit var mPoisList: MutableList<PoiItem>

    private lateinit var geocodeAdapter: GeocodeAdapter

    private var poiItem: PoiItem? = null

    private lateinit var location: AMapLocation

    override fun initAppBar() {
        getTitleBar().title = "选择地点"
        getTitleBar().setRightTitleColor(Color.parseColor("#333333"))
        getTitleBar().rightTitle = getString(R.string.txt_confirm)
    }

    override fun onRightClick(titleBar: TitleBar?) {
        if (poiItem != null) {
            RxBus.getDefault().post(BusEvent(EventTypes.SELECT_SITE.code, poiItem))
            finish()
        } else {
            ToastUtils.showShort("请选择地点")
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        mBinding.mapView.onSaveInstanceState(outState)
    }

    override fun initListener() {
        KeyboardUtils.registerSoftInputChangedListener(this, KeyboardUtils.OnSoftInputChangedListener {
            Logs.d("registerSoftInputChangedListener $it")
            if (it > 0) {
                // 软件盘弹出
                keyBoardShowStatus()
            } else {
                // 软件盘隐藏
                keyBoardHiddenStatus()
            }
        })
    }

    override fun initData(bundle: Bundle?) {
        mBinding.mapView.onCreate(bundle)
        if (!this::aMap.isInitialized) {
            aMap = mBinding.mapView.map
        }
        initMapLocation()
    }

    override fun onResume() {
        super.onResume()
        mBinding.mapView.onResume()
    }

    override fun onPause() {
        super.onPause()
        mBinding.mapView.onPause()
    }

    override fun onDestroy() {
        if (mLocationClient != null) {
            mLocationClient!!.stopLocation()
            mLocationClient!!.onDestroy()
        }
        mBinding.mapView.onDestroy()
        KeyboardUtils.unregisterSoftInputChangedListener(window)
        super.onDestroy()
    }

    /**
     * 初始化地图定位
     */
    private fun initMapLocation() {
        val myLocationStyle = MyLocationStyle()
        // locationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.em_unread_count_bg));
        myLocationStyle.strokeColor(Color.BLACK)
        myLocationStyle.radiusFillColor(Color.argb(100, 0, 0, 180))
        myLocationStyle.strokeWidth(1.0f)
        // 缩放比例
        aMap.moveCamera(CameraUpdateFactory.zoomTo(16f))
        // 设置定位蓝点的Style
        aMap.myLocationStyle = myLocationStyle
        // 地图定位
        aMap.setLocationSource(this)
        // 设置默认定位按钮是否显示
        aMap.uiSettings.isMyLocationButtonEnabled = true
        // 设置缩放按钮是否显示
        aMap.uiSettings.isZoomControlsEnabled = false
        // 设置比例尺控件是否显示
        aMap.uiSettings.isScaleControlsEnabled = false
        // 设置为true表示启动显示定位蓝点，false表示隐藏定位蓝点并不进行定位
        aMap.isMyLocationEnabled = true
        //监听地图发生变化之后
        aMap.setOnCameraChangeListener(object : AMap.OnCameraChangeListener {
            override fun onCameraChange(cameraPosition: CameraPosition?) {

                if (cameraPosition != null) {
                    if (getZoomB != cameraPosition.zoom) {
                        Logs.d("onCameraChange 缩放了，不作为 ${cameraPosition.zoom}")
                        getZoomB = cameraPosition.zoom
                    } else {
                        point = LatLng(cameraPosition.target.latitude, cameraPosition.target.longitude)
                        marker?.position = point
                    }
                }
            }

            override fun onCameraChangeFinish(cameraPosition: CameraPosition?) {
                if (cameraPosition != null) {
                    if (getZoomB != cameraPosition.zoom) {
                        Logs.d("onCameraChangeFinish 缩放了，不作为 ${cameraPosition.zoom}")
                        getZoomB = cameraPosition.zoom
                    } else {
                        Logs.d("onCameraChangeFinish  ${cameraPosition.zoom}")
                        //发生变化时获取到经纬度传递逆地理编码获取周边数据
                        reGeocodeSearch(cameraPosition.target.latitude, cameraPosition.target.longitude, 1500)
                    }
                }
            }
        })

    }

    override fun activate(onLocationChangedListener: LocationSource.OnLocationChangedListener?) {
        this.mListener = onLocationChangedListener
        Logs.d("activate")
        if (mLocationClient == null) {
            mLocationClient = AMapLocationClient(this)
            mLocationClient!!.setLocationListener(this)

            mLocationOption = AMapLocationClientOption()
            //只定位一次
            mLocationOption!!.isOnceLocation = true
            mLocationOption!!.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
            mLocationClient!!.setLocationOption(mLocationOption)
            mLocationClient!!.startLocation()
        }
    }

    override fun deactivate() {
        mListener = null
        if (mLocationClient != null) {
            mLocationClient!!.stopLocation()
            mLocationClient!!.onDestroy()
        }
        mLocationClient = null
        mLocationOption = null
    }


    override fun onLocationChanged(location: AMapLocation?) {
        if (location != null && mListener != null) {
            if (location.errorCode == 0) {
                mListener!!.onLocationChanged(location)
                val mLatitude: Double = location.latitude
                val mLongitude: Double = location.longitude
                this.location = location
                reGeocodeSearch(mLatitude, mLongitude, 1500)

                if (marker == null) {
                    point = LatLng(location.latitude, location.longitude)
                    //地图发生变化之后描绘mark
                    marker = aMap.addMarker(MarkerOptions()
                        .position(point)
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_select_point)))
                }
            } else {
                val errorText = "faild to located" + location.errorCode + ":" + location.errorInfo
                Logs.d(errorText)
            }
        }
    }

    override fun onPoiSearched(result: PoiResult?, p1: Int) {
        if (p1 == 1000) {
            if (result != null) {
                // 当搜索不到poiitem数据时，会返回含有搜索关键字的城市信息
                if (!result.pois.isNullOrEmpty()) {
                    mPoisList.clear()
                    mPoisList = result.pois
                }
                setAddressList(mPoisList)
            }
        }
    }

    override fun onPoiItemSearched(p0: PoiItem?, p1: Int) {

    }

    /**
     * 逆编码获取定位后的附近地址
     * @param latitude
     * @param longitude
     * @param distances 设置查找范围
     */
    private fun reGeocodeSearch(latitude: Double, longitude: Double, distances: Int) {
        val point = LatLonPoint(latitude, longitude)
        val geocodeSearch = GeocodeSearch(this)
        val reGeocodeQuery = RegeocodeQuery(point, distances.toFloat(), GeocodeSearch.AMAP)
        geocodeSearch.getFromLocationAsyn(reGeocodeQuery)

        geocodeSearch.setOnGeocodeSearchListener(object : GeocodeSearch.OnGeocodeSearchListener {
            override fun onRegeocodeSearched(regeocodeResult: RegeocodeResult?, rCode: Int) {
                if (1000 == rCode) {
                    if (regeocodeResult != null) {
                        val address: RegeocodeAddress = regeocodeResult.regeocodeAddress
                        val province = address.province //省或直辖市
                        val city = address.city //地级市或直辖市
                        val district = address.district //区或县或县级市
                        val area = address.businessAreas[0].name
                        Logs.d("$province == $city == $district == $area")
                        mPoisList = address.pois //获取周围兴趣点
                        setAddressList(mPoisList)
                    }
                }
            }

            override fun onGeocodeSearched(p0: GeocodeResult?, p1: Int) {

            }
        })
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun setAddressList(data: List<PoiItem>) {
        if (data.isNotEmpty()) {
            if (!this::geocodeAdapter.isInitialized) {
                mBinding.recyclerAddress.layoutManager = LinearLayoutManager(this,
                    LinearLayoutManager.VERTICAL, false)
                geocodeAdapter = GeocodeAdapter(data as MutableList<PoiItem>)
                mBinding.recyclerAddress.adapter = geocodeAdapter

                poiItem  = geocodeAdapter.data[0]
                // 选择事件
                geocodeAdapter.setOnItemClickListener { adapter, view, position ->
                    geocodeAdapter.setSelectClickId(position)
                    poiItem = adapter.data[position] as PoiItem

                    point = LatLng(poiItem!!.latLonPoint.latitude, poiItem!!.latLonPoint.longitude)
                    marker?.position = point

                    aMap.moveCamera(CameraUpdateFactory.newCameraPosition(CameraPosition(point, 16f, 0f, 0f)))
                }

            } else {
                geocodeAdapter.data = data as MutableList<PoiItem>
                geocodeAdapter.notifyDataSetChanged()
                poiItem = geocodeAdapter.data[geocodeAdapter.clickId]
            }
        }
    }

    /**
     * 根据类型 转换 坐标
     */
    fun convert(sourceLatLng: LatLng?): LatLng? {
        val converter = CoordinateConverter(this)
        // CoordType.GPS 待转换坐标类型
        converter.from(CoordinateConverter.CoordType.GPS)
        // sourceLatLng待转换坐标点
        converter.coord(sourceLatLng)
        // 执行转换操作
        return converter.convert()
    }


    private fun searchAddress(etText: String) {
        val poiQuery = PoiSearch.Query(etText, "", location.cityCode)
        val lp = LatLonPoint(location.latitude, location.longitude)
        poiQuery.pageSize = 15
        poiQuery.pageNum = 2
        poiQuery.location = lp
        val poiSearch = PoiSearch(this, poiQuery)
        poiSearch.setOnPoiSearchListener(this)
        poiSearch.searchPOIAsyn()
    }

    /**
     * 弹出软件盘 设置列表高度
     */
    private fun keyBoardShowStatus() {
        mPoisList.clear()
        geocodeAdapter.clickId = -1
        geocodeAdapter.notifyDataSetChanged()

        val layoutParams = mBinding.llLayout.layoutParams as (LinearLayout.LayoutParams)
        layoutParams.weight = 3f
        mBinding.llLayout.layoutParams = layoutParams

        mBinding.tvSearch.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

            }

            override fun afterTextChanged(s: Editable?) {
                searchAddress(s.toString())
            }
        })
    }

    /**
     * 收回软键盘、恢复列表高度
     */
    private fun keyBoardHiddenStatus() {
        val layoutParams = mBinding.llLayout.layoutParams as (LinearLayout.LayoutParams)
        layoutParams.weight = 1f
        mBinding.llLayout.layoutParams = layoutParams
    }
}